diff --git a/models/repo.go b/models/repo.go
index 99ab247566..43fb1e0c73 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -163,6 +163,7 @@ func NewRepoContext() {
 type Repository struct {
 	ID            int64  `xorm:"pk autoincr"`
 	OwnerID       int64  `xorm:"UNIQUE(s)"`
+	OwnerName     string `xorm:"-"`
 	Owner         *User  `xorm:"-"`
 	LowerName     string `xorm:"UNIQUE(s) INDEX NOT NULL"`
 	Name          string `xorm:"INDEX NOT NULL"`
@@ -225,9 +226,17 @@ func (repo *Repository) MustOwner() *User {
 	return repo.mustOwner(x)
 }
 
+// MustOwnerName always returns valid owner name to avoid
+// conceptually impossible error handling.
+// It returns "error" and logs error details when error
+// occurs.
+func (repo *Repository) MustOwnerName() string {
+	return repo.mustOwnerName(x)
+}
+
 // FullName returns the repository full name
 func (repo *Repository) FullName() string {
-	return repo.MustOwner().Name + "/" + repo.Name
+	return repo.MustOwnerName() + "/" + repo.Name
 }
 
 // HTMLURL returns the repository HTML URL
@@ -479,6 +488,41 @@ func (repo *Repository) mustOwner(e Engine) *User {
 	return repo.Owner
 }
 
+func (repo *Repository) getOwnerName(e Engine) error {
+	if len(repo.OwnerName) > 0 {
+		return nil
+	}
+
+	if repo.Owner != nil {
+		repo.OwnerName = repo.Owner.Name
+		return nil
+	}
+
+	u := new(User)
+	has, err := e.ID(repo.OwnerID).Cols("name").Get(u)
+	if err != nil {
+		return err
+	} else if !has {
+		return ErrUserNotExist{repo.OwnerID, "", 0}
+	}
+	repo.OwnerName = u.Name
+	return nil
+}
+
+// GetOwnerName returns the repository owner name
+func (repo *Repository) GetOwnerName() error {
+	return repo.getOwnerName(x)
+}
+
+func (repo *Repository) mustOwnerName(e Engine) string {
+	if err := repo.getOwnerName(e); err != nil {
+		log.Error(4, "Error loading repository owner name: %v", err)
+		return "error"
+	}
+
+	return repo.OwnerName
+}
+
 // ComposeMetas composes a map of metas for rendering external issue tracker URL.
 func (repo *Repository) ComposeMetas() map[string]string {
 	unit, err := repo.GetUnit(UnitTypeExternalTracker)
@@ -590,7 +634,7 @@ func (repo *Repository) GetBaseRepo() (err error) {
 }
 
 func (repo *Repository) repoPath(e Engine) string {
-	return RepoPath(repo.mustOwner(e).Name, repo.Name)
+	return RepoPath(repo.mustOwnerName(e), repo.Name)
 }
 
 // RepoPath returns the repository path
@@ -2141,7 +2185,7 @@ func ReinitMissingRepositories() error {
 // SyncRepositoryHooks rewrites all repositories' pre-receive, update and post-receive hooks
 // to make sure the binary and custom conf path are up-to-date.
 func SyncRepositoryHooks() error {
-	return x.Where("id > 0").Iterate(new(Repository),
+	return x.Cols("owner_id", "name").Where("id > 0").Iterate(new(Repository),
 		func(idx int, bean interface{}) error {
 			if err := createDelegateHooks(bean.(*Repository).RepoPath()); err != nil {
 				return fmt.Errorf("SyncRepositoryHook: %v", err)
diff --git a/models/wiki.go b/models/wiki.go
index 3e0d1b9ce8..4637a449cd 100644
--- a/models/wiki.go
+++ b/models/wiki.go
@@ -67,7 +67,7 @@ func WikiPath(userName, repoName string) string {
 
 // WikiPath returns wiki data path for given repository.
 func (repo *Repository) WikiPath() string {
-	return WikiPath(repo.MustOwner().Name, repo.Name)
+	return WikiPath(repo.MustOwnerName(), repo.Name)
 }
 
 // HasWiki returns true if repository has wiki.